package xju.rjxy.shop.web.controller;

import com.alibaba.fastjson.JSON;
import xju.rjxy.shop.common.framework.simplemvc.RequestMapping;
import xju.rjxy.shop.common.utils.JSONUtil;
import xju.rjxy.shop.common.utils.Result;
import xju.rjxy.shop.model.domain.Game;
import xju.rjxy.shop.model.domain.User;
import xju.rjxy.shop.model.domain.UserGame;
import xju.rjxy.shop.service.IGameService;
import xju.rjxy.shop.service.IUserGameService;
import xju.rjxy.shop.service.IUserService;
import xju.rjxy.shop.service.impl.GameServiceImpl;
import xju.rjxy.shop.service.impl.UserGameServiceImpl;
import xju.rjxy.shop.service.impl.UserServiceImpl;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

/**
 * 购买游戏控制层
 */
@RequestMapping("/api/purchase")
public class PurchaseController {
    private final IUserService userService = new UserServiceImpl();
    private final IGameService gameService = new GameServiceImpl();
    private final IUserGameService userGameService = new UserGameServiceImpl();

    /**
     * 购买游戏
     * POST /api/purchase/game.do
     */
    @RequestMapping("/game.do")
    public void purchaseGame(HttpServletRequest request, HttpServletResponse response) {
        System.out.println("[DEBUG] PurchaseController.purchaseGame - 开始处理购买游戏请求");
        try {
            // 读取请求参数
            String userIdStr = request.getParameter("userId");
            String gameIdStr = request.getParameter("gameId");
            
            System.out.println("[DEBUG] PurchaseController.purchaseGame - 请求参数 userId: " + userIdStr + ", gameId: " + gameIdStr);
            
            // 如果参数为空，尝试从JSON请求体读取
            if ((userIdStr == null || gameIdStr == null) || 
                (userIdStr.isEmpty() || gameIdStr.isEmpty())) {
                System.out.println("[DEBUG] PurchaseController.purchaseGame - 尝试从JSON请求体读取参数");
                Map<String, Object> requestBody = readRequestBody(request, Map.class);
                userIdStr = requestBody.get("userId") != null ? requestBody.get("userId").toString() : null;
                gameIdStr = requestBody.get("gameId") != null ? requestBody.get("gameId").toString() : null;
                System.out.println("[DEBUG] PurchaseController.purchaseGame - JSON参数 userId: " + userIdStr + ", gameId: " + gameIdStr);
            }
            
            // 参数验证
            if (userIdStr == null || userIdStr.trim().isEmpty()) {
                System.err.println("[ERROR] PurchaseController.purchaseGame - 用户ID不能为空");
                JSONUtil.printByJSON(response, Result.fail("用户ID不能为空"));
                return;
            }
            
            if (gameIdStr == null || gameIdStr.trim().isEmpty()) {
                System.err.println("[ERROR] PurchaseController.purchaseGame - 游戏ID不能为空");
                JSONUtil.printByJSON(response, Result.fail("游戏ID不能为空"));
                return;
            }
            
            Integer userId = Integer.parseInt(userIdStr);
            Integer gameId = Integer.parseInt(gameIdStr);
            
            System.out.println("[DEBUG] PurchaseController.purchaseGame - 解析后的参数 userId: " + userId + ", gameId: " + gameId);
            
            // 1. 验证用户是否存在
            User user = userService.getUserById(userId);
            if (user == null) {
                System.err.println("[ERROR] PurchaseController.purchaseGame - 用户不存在，userId: " + userId);
                JSONUtil.printByJSON(response, Result.fail("用户不存在"));
                return;
            }
            
            // 2. 验证游戏是否存在且可购买
            Game game = gameService.getGameById(gameId);
            if (game == null) {
                System.err.println("[ERROR] PurchaseController.purchaseGame - 游戏不存在，gameId: " + gameId);
                JSONUtil.printByJSON(response, Result.fail("游戏不存在"));
                return;
            }
            
            // 检查游戏状态（2表示已发布，可购买）
            if (game.getFlag() != 2) {
                System.err.println("[ERROR] PurchaseController.purchaseGame - 游戏不可购买，gameId: " + gameId + ", flag: " + game.getFlag());
                JSONUtil.printByJSON(response, Result.fail("游戏不可购买"));
                return;
            }
            
            // 3. 检查用户是否已购买该游戏
            UserGame existingUserGame = userGameService.getUserGameByUserIdAndGameId(userId, gameId);
            if (existingUserGame != null) {
                System.err.println("[ERROR] PurchaseController.purchaseGame - 用户已购买该游戏，userId: " + userId + ", gameId: " + gameId);
                JSONUtil.printByJSON(response, Result.fail("您已购买该游戏"));
                return;
            }
            
            // 4. 检查用户余额是否足够
            Double gamePrice = game.getPrice();
            Double userBalance = user.getAccountBalance() != null ? user.getAccountBalance() : 0.0;
            
            System.out.println("[DEBUG] PurchaseController.purchaseGame - 游戏价格: " + gamePrice + ", 用户余额: " + userBalance);
            
            if (userBalance < gamePrice) {
                System.err.println("[ERROR] PurchaseController.purchaseGame - 用户余额不足，需要: " + gamePrice + ", 当前: " + userBalance);
                JSONUtil.printByJSON(response, Result.fail("余额不足，请先充值"));
                return;
            }
            
            // 5. 执行购买逻辑
            boolean purchaseSuccess = executePurchase(user, game);
            
            if (purchaseSuccess) {
                System.out.println("[DEBUG] PurchaseController.purchaseGame - 购买成功，userId: " + userId + ", gameId: " + gameId);
                
                // 构建响应数据
                Map<String, Object> resultData = new HashMap<>();
                resultData.put("userId", userId);
                resultData.put("gameId", gameId);
                resultData.put("gameName", game.getGameName());
                resultData.put("purchasePrice", gamePrice);
                resultData.put("remainingBalance", userBalance - gamePrice);
                resultData.put("purchaseTime", LocalDateTime.now());
                
                JSONUtil.printByJSON(response, Result.success(resultData, "购买成功"));
            } else {
                System.err.println("[ERROR] PurchaseController.purchaseGame - 购买失败，userId: " + userId + ", gameId: " + gameId);
                JSONUtil.printByJSON(response, Result.fail("购买失败，请稍后重试"));
            }
            
        } catch (NumberFormatException e) {
            System.err.println("[ERROR] PurchaseController.purchaseGame - 参数格式错误: " + e.getMessage());
            JSONUtil.printByJSON(response, Result.fail("参数格式错误"));
        } catch (Exception e) {
            System.err.println("[ERROR] PurchaseController.purchaseGame - 购买游戏失败: " + e.getMessage());
            e.printStackTrace();
            JSONUtil.printByJSON(response, Result.fail("购买失败: " + e.getMessage()));
        }
    }
    
    /**
     * 批量购买游戏
     * POST /api/purchase/batch.do
     */
    @RequestMapping("/batch.do")
    public void batchPurchaseGames(HttpServletRequest request, HttpServletResponse response) {
        System.out.println("[DEBUG] PurchaseController.batchPurchaseGames - 开始处理批量购买游戏请求");
        try {
            // 读取请求体
            Map<String, Object> requestBody = readRequestBody(request, Map.class);
            
            System.out.println("[DEBUG] PurchaseController.batchPurchaseGames - 原始请求体: " + requestBody);
            
            String userIdStr = requestBody.get("userId") != null ? requestBody.get("userId").toString() : null;
            
            // 修复gameIds的类型转换问题
            java.util.List<Integer> gameIds = new java.util.ArrayList<>();
            Object gameIdsObj = requestBody.get("gameIds");
            
            if (gameIdsObj instanceof java.util.List) {
                java.util.List<?> gameIdsList = (java.util.List<?>) gameIdsObj;
                for (Object item : gameIdsList) {
                    if (item instanceof Integer) {
                        gameIds.add((Integer) item);
                    } else if (item instanceof String) {
                        try {
                            gameIds.add(Integer.parseInt((String) item));
                        } catch (NumberFormatException e) {
                            System.err.println("[ERROR] PurchaseController.batchPurchaseGames - 游戏ID格式错误: " + item);
                            JSONUtil.printByJSON(response, Result.fail("游戏ID格式错误: " + item));
                            return;
                        }
                    } else {
                        System.err.println("[ERROR] PurchaseController.batchPurchaseGames - 游戏ID类型错误: " + item.getClass());
                        JSONUtil.printByJSON(response, Result.fail("游戏ID类型错误"));
                        return;
                    }
                }
            } else {
                System.err.println("[ERROR] PurchaseController.batchPurchaseGames - gameIds不是数组类型");
                JSONUtil.printByJSON(response, Result.fail("游戏ID列表格式错误"));
                return;
            }
            
            System.out.println("[DEBUG] PurchaseController.batchPurchaseGames - 解析后的参数 userId: " + userIdStr + ", gameIds: " + gameIds);
            
            // 参数验证
            if (userIdStr == null || userIdStr.trim().isEmpty()) {
                JSONUtil.printByJSON(response, Result.fail("用户ID不能为空"));
                return;
            }
            
            if (gameIds == null || gameIds.isEmpty()) {
                JSONUtil.printByJSON(response, Result.fail("游戏ID列表不能为空"));
                return;
            }
            
            Integer userId = Integer.parseInt(userIdStr);
            
            // 验证用户是否存在
            User user = userService.getUserById(userId);
            if (user == null) {
                JSONUtil.printByJSON(response, Result.fail("用户不存在"));
                return;
            }
            
            // 计算总价格并验证余额
            Double totalPrice = 0.0;
            java.util.List<Game> gamesToPurchase = new java.util.ArrayList<>();
            
            for (Integer gameId : gameIds) {
                System.out.println("[DEBUG] PurchaseController.batchPurchaseGames - 处理游戏ID: " + gameId);
                
                Game game = gameService.getGameById(gameId);
                if (game == null) {
                    JSONUtil.printByJSON(response, Result.fail("游戏不存在，gameId: " + gameId));
                    return;
                }
                
                if (game.getFlag() != 2) {
                    JSONUtil.printByJSON(response, Result.fail("游戏不可购买，gameId: " + gameId));
                    return;
                }
                
                // 检查是否已购买
                UserGame existingUserGame = userGameService.getUserGameByUserIdAndGameId(userId, gameId);
                if (existingUserGame != null) {
                    JSONUtil.printByJSON(response, Result.fail("您已购买游戏: " + game.getGameName()));
                    return;
                }
                
                totalPrice += game.getPrice();
                gamesToPurchase.add(game);
                System.out.println("[DEBUG] PurchaseController.batchPurchaseGames - 游戏 " + game.getGameName() + " 价格: " + game.getPrice());
            }
            
            Double userBalance = user.getAccountBalance() != null ? user.getAccountBalance() : 0.0;
            System.out.println("[DEBUG] PurchaseController.batchPurchaseGames - 用户余额: " + userBalance + ", 总价格: " + totalPrice);
            
            if (userBalance < totalPrice) {
                JSONUtil.printByJSON(response, Result.fail("余额不足，需要: " + totalPrice + ", 当前: " + userBalance));
                return;
            }
            
            // 执行批量购买
            boolean batchSuccess = executeBatchPurchase(user, gamesToPurchase);
            
            if (batchSuccess) {
                Map<String, Object> resultData = new HashMap<>();
                resultData.put("userId", userId);
                resultData.put("totalPrice", totalPrice);
                resultData.put("remainingBalance", userBalance - totalPrice);
                resultData.put("purchasedCount", gamesToPurchase.size());
                resultData.put("purchaseTime", LocalDateTime.now());
                
                System.out.println("[DEBUG] PurchaseController.batchPurchaseGames - 批量购买成功");
                JSONUtil.printByJSON(response, Result.success(resultData, "批量购买成功"));
            } else {
                System.err.println("[ERROR] PurchaseController.batchPurchaseGames - 批量购买失败");
                JSONUtil.printByJSON(response, Result.fail("批量购买失败，请稍后重试"));
            }
            
        } catch (NumberFormatException e) {
            System.err.println("[ERROR] PurchaseController.batchPurchaseGames - 参数格式错误: " + e.getMessage());
            JSONUtil.printByJSON(response, Result.fail("参数格式错误: " + e.getMessage()));
        } catch (Exception e) {
            System.err.println("[ERROR] PurchaseController.batchPurchaseGames - 批量购买失败: " + e.getMessage());
            e.printStackTrace();
            JSONUtil.printByJSON(response, Result.fail("批量购买失败: " + e.getMessage()));
        }
    }
    
    /**
     * 获取购买历史
     * GET /api/purchase/history.do?userId=xxx&page=1&size=10
     */
    @RequestMapping("/history.do")
    public void getPurchaseHistory(HttpServletRequest request, HttpServletResponse response) {
        System.out.println("[DEBUG] PurchaseController.getPurchaseHistory - 开始获取购买历史");
        try {
            String userIdStr = request.getParameter("userId");
            String pageStr = request.getParameter("page");
            String sizeStr = request.getParameter("size");
            
            System.out.println("[DEBUG] PurchaseController.getPurchaseHistory - 请求参数 userId: " + userIdStr + ", page: " + pageStr + ", size: " + sizeStr);
            
            if (userIdStr == null || userIdStr.trim().isEmpty()) {
                JSONUtil.printByJSON(response, Result.fail("用户ID不能为空"));
                return;
            }
            
            Integer userId = Integer.parseInt(userIdStr);
            int page = pageStr != null ? Integer.parseInt(pageStr) : 1;
            int size = sizeStr != null ? Integer.parseInt(sizeStr) : 10;
            
            // 获取用户游戏列表（按购买时间倒序）
            java.util.List<xju.rjxy.shop.model.vo.UserGameVO> userGameList = userGameService.getUserGameListByUserId(userId);
            
            // 简单分页处理
            int total = userGameList.size();
            int offset = (page - 1) * size;
            int endIndex = Math.min(offset + size, total);
            
            java.util.List<xju.rjxy.shop.model.vo.UserGameVO> pagedList = userGameList.subList(offset, endIndex);
            
            Map<String, Object> resultData = new HashMap<>();
            resultData.put("list", pagedList);
            resultData.put("total", total);
            resultData.put("page", page);
            resultData.put("size", size);
            resultData.put("totalPages", (total + size - 1) / size);
            
            JSONUtil.printByJSON(response, Result.success(resultData));
            
        } catch (NumberFormatException e) {
            JSONUtil.printByJSON(response, Result.fail("参数格式错误"));
        } catch (Exception e) {
            System.err.println("[ERROR] PurchaseController.getPurchaseHistory - 获取购买历史失败: " + e.getMessage());
            e.printStackTrace();
            JSONUtil.printByJSON(response, Result.fail("获取购买历史失败: " + e.getMessage()));
        }
    }
    
    /**
     * 执行购买逻辑
     */
    private boolean executePurchase(User user, Game game) {
        try {
            // 1. 扣除用户余额
            Double currentBalance = user.getAccountBalance() != null ? user.getAccountBalance() : 0.0;
            Double newBalance = currentBalance - game.getPrice();
            user.setAccountBalance(newBalance);
            
            boolean updateBalanceSuccess = userService.updateUserInfo(user);
            if (!updateBalanceSuccess) {
                System.err.println("[ERROR] PurchaseController.executePurchase - 更新用户余额失败");
                return false;
            }
            
            // 2. 创建用户游戏关联记录
            UserGame userGame = new UserGame();
            userGame.setUserId(user.getId());
            userGame.setGameId(game.getId());
            userGame.setPurchaseTime(LocalDateTime.now());
            userGame.setPurchasePrice(game.getPrice());
            userGame.setPlayCount(0);
            userGame.setPlayTime(0);
            userGame.setFlag(2); // 已购买
            userGame.setStatusCode("OWNED");
            
            boolean addUserGameSuccess = userGameService.addUserGame(userGame);
            if (!addUserGameSuccess) {
                System.err.println("[ERROR] PurchaseController.executePurchase - 创建用户游戏关联失败");
                // 回滚余额
                user.setAccountBalance(currentBalance);
                userService.updateUserInfo(user);
                return false;
            }
            
            System.out.println("[DEBUG] PurchaseController.executePurchase - 购买成功，用户ID: " + user.getId() + ", 游戏ID: " + game.getId());
            return true;
            
        } catch (Exception e) {
            System.err.println("[ERROR] PurchaseController.executePurchase - 执行购买逻辑失败: " + e.getMessage());
            e.printStackTrace();
            return false;
        }
    }
    
    /**
     * 执行批量购买逻辑
     */
    private boolean executeBatchPurchase(User user, java.util.List<Game> games) {
        try {
            Double totalPrice = games.stream().mapToDouble(Game::getPrice).sum();
            Double currentBalance = user.getAccountBalance() != null ? user.getAccountBalance() : 0.0;
            Double newBalance = currentBalance - totalPrice;
            
            // 1. 扣除用户余额
            user.setAccountBalance(newBalance);
            boolean updateBalanceSuccess = userService.updateUserInfo(user);
            if (!updateBalanceSuccess) {
                System.err.println("[ERROR] PurchaseController.executeBatchPurchase - 更新用户余额失败");
                return false;
            }
            
            // 2. 批量创建用户游戏关联记录
            for (Game game : games) {
                UserGame userGame = new UserGame();
                userGame.setUserId(user.getId());
                userGame.setGameId(game.getId());
                userGame.setPurchaseTime(LocalDateTime.now());
                userGame.setPurchasePrice(game.getPrice());
                userGame.setPlayCount(0);
                userGame.setPlayTime(0);
                userGame.setFlag(2); // 已购买
                userGame.setStatusCode("OWNED");
                
                boolean addUserGameSuccess = userGameService.addUserGame(userGame);
                if (!addUserGameSuccess) {
                    System.err.println("[ERROR] PurchaseController.executeBatchPurchase - 创建用户游戏关联失败，gameId: " + game.getId());
                    // 回滚余额
                    user.setAccountBalance(currentBalance);
                    userService.updateUserInfo(user);
                    return false;
                }
            }
            
            System.out.println("[DEBUG] PurchaseController.executeBatchPurchase - 批量购买成功，用户ID: " + user.getId() + ", 游戏数量: " + games.size());
            return true;
            
        } catch (Exception e) {
            System.err.println("[ERROR] PurchaseController.executeBatchPurchase - 执行批量购买逻辑失败: " + e.getMessage());
            e.printStackTrace();
            return false;
        }
    }
    
    /**
     * 读取请求体并转换为指定类型
     */
    private <T> T readRequestBody(HttpServletRequest request, Class<T> clazz) throws IOException {
        BufferedReader reader = request.getReader();
        StringBuilder sb = new StringBuilder();
        String line;
        while ((line = reader.readLine()) != null) {
            sb.append(line);
        }
        String json = sb.toString();
        return JSON.parseObject(json, clazz);
    }
} 